package wechat

import (
	"context"
	"fmt"
	"strconv"
	"strings"

	"mall/common/globalkey"
	"mall/common/jwt"
	"mall/common/resultx"
	"mall/common/utils/pointy"
	"mall/service/attachment/rpc/attachmentclient"
	"mall/service/forum/api/internal/svc"
	"mall/service/forum/api/internal/types"
	"mall/service/user/rpc/userclient"

	"github.com/zeromicro/go-zero/core/logx"
)

type UpdateProfileLogic struct {
	logx.Logger
	ctx    context.Context
	svcCtx *svc.ServiceContext
}

func NewUpdateProfileLogic(ctx context.Context, svcCtx *svc.ServiceContext) *UpdateProfileLogic {
	return &UpdateProfileLogic{
		Logger: logx.WithContext(ctx),
		ctx:    ctx,
		svcCtx: svcCtx,
	}
}

func (l *UpdateProfileLogic) UpdateProfile(req *types.UpdateUserProfileReq) (resp *types.BaseMsgResp, err error) { // Todo:
	userId := jwt.GetUserId(l.ctx)
	if userId == 0 {
		return nil, resultx.NewErrCode(resultx.TOKEN_EXPIRE_ERROR)
	}

	var authType *string
	if req.AuthType == nil || len(strings.TrimSpace(*req.AuthType)) == 0 {
		authType = pointy.GetPointer(globalkey.UserAuthTypeWechatMini)
	} else {
		authType = req.AuthType
	}

	newThumbMap := make(map[string]*types.MediaInfo)
	var newMedia []*userclient.UserMediaInfo
	var newMediaIds []string
	var newAttachmentIds []string
	if len(req.Photos) > 0 {
		for _, v := range req.Photos {
			if v.Id != nil && len(*v.Id) > 0 {
				if _, ok := newThumbMap[*v.Id]; !ok { // 忽略重复id
					newThumbMap[*v.Id] = v
					newMediaIds = append(newMediaIds, *v.Id)
				}
			} else {
				var thumbnail *uint32
				if v.Thumbnail != nil && *v.Thumbnail {
					thumbnail = pointy.GetPointer(uint32(1))
				}
				newMedia = append(newMedia, &userclient.UserMediaInfo{ // 第三方图片
					Uid:       v.Uid,
					Url:       v.Url,
					Thumbnail: thumbnail,
					Order:     v.Order,
					AltText:   v.AltText,
					Meta:      v.Details,
				})
			}
		}
	}

	// 根据 newMediaIds 查询 attachments 记录到 user_attachment_relationships
	if len(newMediaIds) > 0 {
		res, err := l.svcCtx.AttachmentRpc.BackendGetFileList(l.ctx, &attachmentclient.FileListReq{
			Ids: pointy.GetPointer(strings.Join(newMediaIds, ",")),
		})
		if err != nil {
			return nil, err
		}

		if len(res.List) > 0 {
			for _, v := range res.List {
				var mediaId *uint64
				if v.Id != nil && len(*v.Id) > 0 {
					if i, err := strconv.ParseInt(*v.Id, 10, 64); err == nil && i > 0 {
						mediaId = pointy.GetPointer(uint64(i))
					}
				}
				var url *string
				if v.Url != nil && len(*v.Url) > 0 {
					url = pointy.GetPointer(fmt.Sprintf("%s%s", l.svcCtx.Config.NfsConf.StaticUrl, *v.Url))
				}
				if url == nil && v.Path != nil && len(*v.Path) > 0 {
					url = pointy.GetPointer(fmt.Sprintf("%s%s", l.svcCtx.Config.NfsConf.ProxyUrl, *v.Path))
				}

				if media, ok := newThumbMap[*v.Id]; ok {
					var thumbnail *uint32
					if media.Thumbnail != nil && *media.Thumbnail {
						thumbnail = pointy.GetPointer(uint32(1))
					}
					newMedia = append(newMedia, &userclient.UserMediaInfo{
						Uid:       media.Uid,
						Id:        mediaId,
						Uri:       media.Url,
						Url:       url,
						Thumbnail: thumbnail,
						Order:     media.Order,
						AltText:   media.AltText,
						Meta:      media.Details,
					})
					newAttachmentIds = append(newAttachmentIds, *v.Id)
				}
			}
		}
	}

	var birthdayHidden *uint32
	if req.BirthdayHidden != nil {
		if *req.BirthdayHidden {
			birthdayHidden = pointy.GetPointer(uint32(1))
		} else {
			birthdayHidden = pointy.GetPointer(uint32(0))
		}
	}
	_, err = l.svcCtx.UserRpc.UpdateProfile(l.ctx, &userclient.UpdateProfileReq{
		AuthType:       authType,
		UserId:         pointy.GetPointer(userId),
		Nickname:       req.Nickname,
		Gender:         req.Gender,
		Birthday:       req.Birthday,
		BirthdayHidden: birthdayHidden,
		NewMedia:       newMedia,
	})
	if err != nil {
		return nil, err
	}

	if len(newAttachmentIds) > 0 {
		_, err = l.svcCtx.AttachmentRpc.BackendCreateLog(l.ctx, &attachmentclient.CreateLogReq{
			FileIds:    newAttachmentIds,
			UserId:     pointy.GetPointer(strconv.FormatInt(int64(userId), 10)),
			Put:        pointy.GetPointer(uint32(1)),
			ObjectId:   pointy.GetPointer(userId),
			ObjectType: pointy.GetPointer(uint32(globalkey.AttachmentLogTypeUserAvatar)),
			Title:      pointy.GetPointer("profile"),
		})
		if err != nil {
			logx.Errorw("UpdateProfile AttachmentRpc BackendCreateLog err", logx.Field("detail", err.Error()))
		}
	}

	return &types.BaseMsgResp{
		Status:  "ok",
		Message: "操作成功",
	}, nil
}
